package cn.jee.cs.controller;

import cn.jee.cs.model.Course;
import cn.jee.cs.model.CourseStudent;
import cn.jee.cs.model.CourseStudentId;
import cn.jee.cs.model.Student;
import cn.jee.cs.vo.CourseComboVo;
import cn.jee.cs.vo.CourseStudentListVo;
import cn.jee.cs.vo.StudentAbbrDto;
import cn.jee.cs.repo.CourseRepository;
import cn.jee.cs.repo.CourseStudentRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/course-student")
@Tag(name = "Enrolling module", description = "选课管理模块")
public class CourseStudentController {
    Logger logger = LoggerFactory.getLogger(CourseStudentController.class);

    @Autowired
    private CourseStudentRepository courseStudentRepo;

    @Autowired
    private CourseRepository courseRepository;

    @GetMapping("/course-student")
    @Operation(summary = "查询选课", description = "查询指定课程或带有选课学生数据的全部课程",
            parameters = {@Parameter(name = "courseId", in = ParameterIn.QUERY, example = "1")})
    public Iterable<CourseStudentListVo> getCourseStudents(
            @RequestParam(value = "courseId", required = false) Long courseId,
            @RequestParam(value = "year", required = false) Integer year) {
        Course course = null;
        if (courseId != null) {
            course = courseRepository.findById(courseId).orElse(null); // 根据实际情况使用Repository查找Course对象
        }

        if (course == null && year == null) {
            return courseStudentRepo.findAllBy();
        } else if (course != null && year == null) {
            return courseStudentRepo.findByCourse(course);
        } else if (course == null) {
            return courseStudentRepo.findById_Year(year);
        } else {
            return courseStudentRepo.findByCourseAndId_Year(course, year);
        }
    }


    @DeleteMapping("/course-student/{courseId}/{studentId}/{year}")
    public void deleteCourseStudentById(@PathVariable Long courseId, @PathVariable Long studentId, @PathVariable Integer year) {
        CourseStudentId id = new CourseStudentId(courseId, studentId, year);
        courseStudentRepo.deleteById(id);
    }

    @GetMapping("/course")
    @Operation(summary = "为下拉列表准备候选课程")
    public List<CourseComboVo> getComboCourses() {
        return courseRepository.findComboCoursesBy();
    }

    @PostMapping("/course-student")
    @Operation(summary = "添加选课", description = "根据提交的“课程id”和“学生id列表”，为指定课程添加学生",
            parameters = {
                    @Parameter(name = "courseId", in = ParameterIn.QUERY, example = "1"),
                    @Parameter(name = "studentIds", in = ParameterIn.QUERY, example = "2,3")
            }
    )
    public void addCourseStudents(
            @Parameter(hidden = true) @RequestParam("courseId") Long courseId,
            @Parameter(example = "2020") @RequestParam("year") Integer year,
            @Parameter(hidden = true) @RequestParam("studentIds") List<Student> students) {

        Course course = courseRepository.findById(courseId).orElse(null);

        // 根据选修学生students，形成多个选修实体对象courseStudents
        List<CourseStudent> courseStudents = students.stream()
                .map(s -> {
                    assert course != null;
                    return new CourseStudent(course, s, year);
                })
                .collect(Collectors.toList());        //使用存储库接口保存所有的选修关系
        courseStudentRepo.saveAll(courseStudents);
    }


    @GetMapping("/student:not-enrolled")
    @Operation(summary = "查询候选课程学生",description = "根据提交的课程id查询未选择该课程的学生", parameters = @Parameter(name = "courseId",in = ParameterIn.QUERY,example = "1"))
    public List<StudentAbbrDto> findCandidatesOfCourse(
            @Parameter(hidden = true) @RequestParam("courseId") Course course) {
        return courseStudentRepo.findStudentsByNotChosenCourse(course);
    }

}
